import Log4R from "../log/Log4R";

const loginfo = Log4R.getLog('info');
const UserInputService = game.GetService('UserInputService');
function onNoParent(instance: Instance, call: (i: Instance) => void) {
    const ac = instance.AncestryChanged.Connect((i, p) => {
        if (!p) {
            ac.Disconnect();
            call(instance)
        }

    })
    return ac
}
/** 返回是否为客户端玩家角色 */
function isLocalPlayerCharacter(c: Model) {

    if (game.GetService('RunService').IsClient() && c === game.GetService('Players').LocalPlayer.Character) {
        return true
    }
    return false
}
function getByPath<T>(path: string, root: Instance) {
    let node: Instance = root;
    const segs = path.split('.');
    segs.forEach((seg: string, index: number) => {
        node = node.WaitForChild(seg);
    })
    return node as unknown as T;
}
/**
 * 获取从root开始计算的第level层级的祖先
 * @param instance 
 * @param level 
 * @param root 
 * @returns 
 */
function getAncestorByLevel(instance: Instance, level: number, root = game.Workspace) {

    const parents = getAncestors(instance, root)
    const result = parents[level]
    if (!result) {
        loginfo?.info('can not find level of ' + level, parents)
    }
    // loginfo?.info('parents ' + level, parents)
    return parents[level]
}
/**
 * 获取从root开始获取祖先
 * @param instance 
 * @param level 
 * @param root 
 * @returns 
 */
function getAncestors(instance: Instance, root = game.Workspace) {
    let node = instance;
    const parents = new Array<Instance>()
    while (node.Parent && node !== root) {
        parents.unshift(node);
        node = node.Parent
    }
    return parents
}
function waitForDescendant<T extends keyof CreatableInstances>(instance: Instance, t: T) {
    let r = instance.GetDescendants().find(c => c.IsA(t))

    while (!r) {
        waitForFirst(instance.ChildAdded, instance.DescendantAdded)
        r = instance.GetDescendants().find(c => c.IsA(t))
    }
    return r as CreatableInstances[T]
}

function waitForChild<T extends keyof CreatableInstances>(instance: Instance, name: string, t: T) {
    let r = instance.GetChildren().find(c => c.IsA(t) && c.Name === name)
    while (!r) {
        waitForFirst(instance.ChildAdded)
        r = instance.GetChildren().find(c => c.IsA(t) && c.Name === name)
    }
    return r as CreatableInstances[T]
}
function waitForFirst(...rbxs: RBXScriptSignal[]) {
    const shunt = new Instance("BindableEvent");

    let slots: RBXScriptConnection[] = [];
    const fire = () => {
        slots.forEach(c => c)
        return shunt.Fire(rbxs)
    }
    slots = rbxs.map(rbx => rbx.Connect(fire))
    return shunt.Event.Wait()
}
/** 返回是否是触屏 */
function getTouchEnabled() {
    return UserInputService.TouchEnabled
}
const common = {
    getTouchEnabled,
    waitForDescendant,
    waitForChild,
    waitForFirst,
    getAncestorByLevel,
    getAncestors,
    getByPath,
    onNoParent,
    isLocalPlayerCharacter
}
export default common;